home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -in_the_mag- / banging_the_metal / demo / charmode64x16_bas < prev    next >
Text File  |  2000-01-01  |  15KB  |  370 lines

  1. 100 REMark Custom Amiga Qdos character-mapped screens
  2. 110 REMark 2345678901234567890123456789012345678901234567890123456789012345678901234
  3. 120 SCR_PRIORITY 4,1 :REMark Priority of Qdos, not custom, screen
  4. 130 REMark OCS 15KHz demonstration version 0.17, SNG January 2000
  5. 135 REMark V0.17 updates: finds chip RAM even if Qdos is loaded high
  6. 137 REMark Uses an animated fount in modes with dynamic fount updates
  7. 140 WINDOW #2,512,200,0,0 : MODE 4 : CSIZE #0,2,0 : ACE_OFF : BLIT_ON
  8. 150 custom=HEX("DFF000")
  9. 160 pagesize=2^16
  10. 170 chipspace=pagesize*3 :REMark Make sure we get two complete pages
  11. 180 REMark All structures start in one 64K page (xx0000) so that we only need
  12. 190 REMark to vary the low pointer words to move them. The Copper list may
  13. 200 REMark extend to a second page if thousands of characters are in use.
  14. 210 HeadLines%=30 :REMark Pixel lines at top of screen above character map area
  15. 220 CharHeight%=16 :REMark 1..16, 10=Qdos, 12=TRS-80, 8=PET
  16. 230 CharLines%=16 : CharColumns%=64 :REMark 32/40/64/80; ALWAYS CharWidth%=8
  17. 240 BlitFount=(CharHeight%=8 AND CharColumns%<=40) :REMark Set for 8x8 fount update
  18. 250 BlitChars=(CharColumns%*CharLines%)<1025 :REMark Unpack CharMap each LoRes field
  19. 260 ShowTime=1 :REMark Set this flag for traditional stripes showing blitter phases
  20. 270 lines%=HeadLines%+CharLines%*CharHeight%
  21. 280 IF lines%<192 THEN PRINT"Too few lines for OCS! - add HeadLines!":STOP
  22. 290 IF lines%>287 THEN PRINT #0;"Too many lines for PAL!":STOP
  23. 300 width%=CharColumns% :REMark Bytes per line per bitplane (EVEN!)
  24. 310 last_sprite%=0 :REMark This one doesn't use sprites at all
  25. 320 IF width% && 1 : PRINT #0;"Uneven bitplane width": STOP
  26. 330 REMark At least 64 pixels fetched are masked by scrolling
  27. 340 border%=0/4 :REMark Extra bytes per line, 8..24, for scrolling
  28. 350 IF border% && 1 : PRINT #0;"Uneven bitplane border": STOP
  29. 360 left_edge%=152+8*last_sprite% :REMark Low resolution pixels
  30. 370 IF (CharColumns% MOD 40)=0 THEN left_edge%=left_edge%-40
  31. 380 IF CharColumns%=32 THEN left_edge%=left_edge%-20
  32. 390 top_line%=312-lines% :REMark 64 for 192 lines? CBM 1960 range is 26+
  33. 400 IF top_line%>64 THEN LET top_line%=64 :REMark Stay near top of screen
  34. 410 PRINT #0;"Total"!border%+width%!"bytes per pixel line"
  35. 420 DMACON_R=2
  36. 430 COPCON=46
  37. 440 BLTCON0=64
  38. 450 BLTCON1=66
  39. 460 BLTMASK=68
  40. 470 BLTBPT=76
  41. 480 BLTAPT=80
  42. 490 BLTDPT=84
  43. 500 BLTSIZE=88
  44. 510 BLTBMOD=98
  45. 520 BLTAMOD=100
  46. 530 BLTDMOD=102
  47. 540 BLTCDAT=112
  48. 550 COP1LC=HEX("80")
  49. 560 DIWSTART=HEX("8E")
  50. 570 DIWSTOP=HEX("90")
  51. 580 DDFSTART=HEX("92")
  52. 590 DDFSTOP=HEX("94")
  53. 600 DMACON_W=HEX("96")
  54. 610 BPL1PT=HEX("E0")
  55. 620 BPLCON0=HEX("100")
  56. 630 BPLCON1=HEX("102")
  57. 640 BPLCON2=HEX("104")
  58. 650 BPLCON3=HEX("106")
  59. 660 BPL1MOD=HEX("108")
  60. 670 BPL2MOD=HEX("10A")
  61. 680 SPR0PTH=HEX("120")
  62. 690 SPR0PTL=HEX("122")
  63. 700 COLOUR0=HEX("180")
  64. 710 COLOUR17=HEX("1A2")
  65. 720 COLOUR18=HEX("1A4")
  66. 730 COLOUR19=HEX("1A6")
  67. 740 COLOUR1=HEX("182")
  68. 750 HTOTAL=HEX("1C0")
  69. 760 HSSTOP=HEX("1C2")
  70. 770 HBSTART=HEX("1C4")
  71. 780 HBSTOP=HEX("1C6")
  72. 790 VTOTAL=HEX("1C8")
  73. 800 VSSTOP=HEX("1CA")
  74. 810 VBSTART=HEX("1CC")
  75. 820 VBSTOP=HEX("1CE")
  76. 830 BEAMCON0=HEX("1DC")
  77. 840 HSSTART=HEX("1DE")
  78. 850 VSSTART=HEX("1E0")
  79. 860 HCENTRE=HEX("1E2")
  80. 870 DIWHIGH=HEX("1E4")
  81. 880 FMODE=HEX("1FC")
  82. 890 :
  83. 900 REMark Errors must return to Qdos mode
  84. 910 ql_off=0
  85. 920 WHEN ERRor 
  86. 930 IF ql_off : QL_ON
  87. 940 PRINT #0;"At ";ERLIN; : REPORT
  88. 950 STOP
  89. 960 END WHEN 
  90. 970 :
  91. 980 CLCHP
  92. 990 cpu_blit=0 :REMark Clear for COPPER_BLITs
  93. 1000 MAKE_CLIST
  94. 1010 BLIT_OFF : PAUSE 10
  95. 1020 screen=backdrop
  96. 1030 POKE_W COPCON+custom,2*(NOT cpu_blit) :REMark Allow Copper to Blit
  97. 1035 FOR i=CharMap TO CharMap+CharLines%*CharColumns%-1
  98. 1040   POKE i,0:REMark (i-CharMap) && 7
  99. 1045 END FOR i : IF BlitFount THEN CHAR_GRID : REMark for 0.17 animation
  100. 1050 CUSTOM_ON
  101. 1060 i=0 : IF BlitFount THEN BorderLines%=4 : ELSE BorderLines%=CharLines%
  102. 1070 REPeat poll
  103. 1080   IF INKEY$(#0,1)<>"" : EXIT poll
  104. 1090   i=((i+1) && 255)
  105. 1095   IF BlitFount THEN POKE$ fount+4096,PEEK$(patterns+((i*8) && 56),8)
  106. 1100   POKE$ CharMap,FILL$(CHR$(i),CharColumns%*BorderLines%)
  107. 1105   IF BlitFount : POKE$ CharMap+CharColumns%*(CharLines%-BorderLines%),FILL$(CHR$(i+1),CharColumns%*BorderLines%)
  108. 1110 END REPeat poll
  109. 1120 QL_ON
  110. 1130 STOP
  111. 1140 :
  112. 1150 REMark Copper list codegen PROCs
  113. 1160 :
  114. 1170 DEFine PROCedure MOVE(value%,reg%)
  115. 1180 POKE_W copper,reg%
  116. 1190 POKE_W copper+2,value%
  117. 1200 copper=copper+4
  118. 1210 END DEFine MOVE
  119. 1220 :
  120. 1230 DEFine PROCedure WAIT(x%,y%)
  121. 1240 POKE_W copper,(y% && 255)*256+(x% && 254)+1
  122. 1250 POKE_W copper+2,32766 :REMark Blitter wait & use all X/Y bits
  123. 1260 copper=copper+4
  124. 1270 END DEFine WAIT
  125. 1280 :
  126. 1290 DEFine PROCedure SKIP(x%,y%)
  127. 1300 POKE_W copper,(y% && 255)*256+(x% && 254)+1
  128. 1310 POKE_W copper+2,32767 :REMark Blitter wait & use all X/Y bits
  129. 1320 copper=copper+4
  130. 1330 END DEFine SKIP
  131. 1340 :
  132. 1350 DEFine PROCedure MAKE_CLIST
  133. 1360 LOCal y,sp :REMark Creates lots of globals
  134. 1370 base=ALCHP(chipspace)
  135. 1380 IF base<1 OR base+chipspace>=2^21
  136. 1390   IF base>0 : RECHP base
  137. 1400   base=2^21-2^17:REMark 0.17 PRINT #0;"Required Chip RAM not found!" : STOP
  138. 1410 END IF 
  139. 1420 page=INT(base/pagesize)+1
  140. 1430 pagebase=page*pagesize : backdrop=pagebase+8192 :REMark Obsolete?
  141. 1440 line_length%=width%+border%
  142. 1450 fount_low=0 : Plane=pagebase+8192 : CharMap=Plane+line_length%*lines%+128
  143. 1460 fount=fount_low+pagebase
  144. 1470 PRINT #0;"Loading fount for character height ";CharHeight%
  145. 1480 LOAD_FOUNT
  146. 1490 INK #2,7 : PAPER #2,0 : CLS #2 : LIST 100 TO 200
  147. 1500 PAUSE 10 : REMark 0.17 Allow time for update
  148. 1510 QDOS2 Plane
  149. 1520 :
  150. 1530 REMark Ensure line alignment, then make the actual copper list
  151. 1540 copper=CharMap+CharColumns%*CharLines%
  152. 1550 copper=16+INT(copper/16)*16
  153. 1560 clist=copper
  154. 1570 PRINT #0;"Setting up copper list ";
  155. 1580 MOVE #page TO BPL1PT
  156. 1590 MOVE #page TO BLTAPT
  157. 1600 MOVE #page TO BLTBPT
  158. 1610 MOVE #page TO BLTDPT
  159. 1620 MOVE #8192 TO BPL1PT+2
  160. 1630 IF CharColumns%>40
  161. 1640   MOVE #HEX("9200") TO BPLCON0 :REMark Hires Colour, 1 bitplane
  162. 1650 ELSE 
  163. 1660   MOVE #HEX("1200") TO BPLCON0 :REMark LoRes Colour, one plane
  164. 1670 END IF 
  165. 1680 MOVE #0 TO BPLCON3 :REMark No special AGA tricks
  166. 1690 MOVE #0 TO COLOUR0 :REMark Black background
  167. 1700 MOVE #HEX("0CC5") TO COLOUR1 : REMark Bright yellow foreground
  168. 1710 MOVE #top_line%*256+left_edge% TO DIWSTART :REMark True left limit
  169. 1720 IF CharColumns%>40
  170. 1730   MOVE #(top_line%+lines%)*256+left_edge%+width%*4+8 TO DIWSTOP
  171. 1740 ELSE 
  172. 1745   zap=copper+2 :REMark Next line is dodgy and may need correction
  173. 1750   MOVE #(top_line%+lines%)*256+(255 && (left_edge%+width%*8+16)) TO DIWSTOP
  174. 1755   IF CharColumns%=32 THEN POKE zap+1,164 :REMark Bodge!
  175. 1760 END IF 
  176. 1770 MOVE #left_edge% DIV 2 TO DDFSTART :REMark Hardware stop is at 18
  177. 1780 IF CharColumns%>40
  178. 1790   MOVE #(left_edge% DIV 2)+4*(width% DIV 2)-8 TO DDFSTOP :REMark Limit 204
  179. 1800 ELSE 
  180. 1810   MOVE #(left_edge% DIV 2)+4*width%-8 TO DDFSTOP :REMark Limit 204
  181. 1820 END IF 
  182. 1830 MOVE #HEX("2100") TO DIWHIGH  :REMark Set H8 and V8 (ECS only!)
  183. 1840 MOVE #0 TO BPL1MOD
  184. 1850 IF NOT cpu_blit THEN MAKE_COPPER_BLITS
  185. 1860 WAIT 255,255
  186. 1870 WAIT 255,255 :REMark Braces
  187. 1880 END DEFine MAKE_CLIST
  188. 1890 :
  189. 1900 DEFine PROCedure QL_ON
  190. 1910 POKE_W custom+DMACON_W,1024
  191. 1920 POKE_W custom+DMACON_W,32768+ql_dmacon
  192. 1930 POKE_L custom+COP1LC,HEX("18600")
  193. 1940 PAUSE 1
  194. 1950 POKE_W custom+COLOUR0,0
  195. 1960 POKE_W custom+COLOUR1,15 :REMark *256 for red
  196. 1970 BLIT_ON : ql_off=0
  197. 1980 END DEFine QL_ON
  198. 1990 :
  199. 2000 DEFine PROCedure CUSTOM_ON
  200. 2010 BLIT_OFF
  201. 2020 ql_off=1
  202. 2030 PAUSE 1
  203. 2040 ql_dmacon=PEEK_W(custom+DMACON_R)
  204. 2050 POKE_L custom+COP1LC,clist
  205. 2060 PAUSE 1
  206. 2070 POKE_W custom+DMACON_W,32 :REMark No sprites
  207. 2080 END DEFine CUSTOM_ON
  208. 2090 :
  209. 2100 DEFine PROCedure QDOS2(bitmap)
  210. 2110 REMark Test routine to throw a Qdos screen into a custom bitplane
  211. 2120 LOCal win_height,win_width,win_base,y :REMark GLOBAL line_length%
  212. 2130 win_height=lines%-1 :REMark Lines numbered from 0
  213. 2140 IF win_height>129 THEN win_height=129
  214. 2150 win_width =64 :REMark Bytes
  215. 2160 PRINT #0;"Copying Qdos window ";win_width*8;"x";win_height+1
  216. 2170 win_base=65536 :REMark Amiga bitplane of Qdos Screen
  217. 2180 FOR y=0 TO win_height
  218. 2190   POKE$ bitmap+y*line_length%,PEEK$(win_base,win_width)
  219. 2200   win_base=win_base+win_width
  220. 2210 END FOR y
  221. 2220 END DEFine QDOS2
  222. 2230 :
  223. 2240 DEFine PROCedure BLIT_CHAR
  224. 2250 IF BlitFount THEN charGap=16 : ELSE charGap=32
  225. 2260 MOVE #fount_low+66*charGap TO BLTBPT+2
  226. 2270 MOVE #fount_low+97*charGap TO BLTAPT+2
  227. 2280 MOVE #N TO BLTDPT+2 : N=N+2
  228. 2290 MOVE #1+CharHeight%*64 TO BLTSIZE
  229. 2300 WAIT COL,LIN :REMark Effectively WaitBlit
  230. 2310 COL=COL+GAP : IF COL>225 THEN COL=COL-226 : LIN=LIN+1
  231. 2320 END DEFine BLIT_CHAR
  232. 2330 :
  233. 2340 DEFine PROCedure SEE
  234. 2350 CUSTOM_ON
  235. 2360 PAUSE
  236. 2370 QL_ON
  237. 2380 END DEFine SEE
  238. 2390 :
  239. 2400 DEFine PROCedure S
  240. 2410 SAVE_O flp1_charmode_bas
  241. 2420 END DEFine S
  242. 2430 :
  243. 2440 DEFine PROCedure LOAD_FOUNT
  244. 2450 REMark fount=ALCHP(256*16*2)
  245. 2460 IF fount>0 AND fount<2^21
  246. 2470   IF BlitFount=0
  247. 2480     REMark 256 characters, 16x16 bit patterns (justify top left)
  248. 2490     IF CharHeight%=16
  249. 2500       LBYTES flp1_Unpacked16x16_fount,fount
  250. 2510     ELSE 
  251. 2520       LBYTES flp1_Unpacked16x9_fount,fount
  252. 2530     END IF 
  253. 2540   ELSE 
  254. 2550     LBYTES flp1_Packed8x8_fount,fount+4096
  255. 2560     REMark 256 characters, 8x8 for expansion
  256. 2570 ELSE 
  257. 2580   PRINT #0;"No chip RAM for fount!"
  258. 2590   STOP
  259. 2600 END IF 
  260. 2610 END DEFine LOAD_FOUNT
  261. 3040 :
  262. 3050 DEFine PROCedure EXPAND_FOUNT(a,b,c)
  263. 3060 REMark Expand 8x8 fount at A to 16x8 fount at B for C characters
  264. 3070 REMark A and B are offsets in the page, C is a WORD count
  265. 3080 IF ShowTime THEN MOVE #6*256 TO COLOUR0 :REMark Signal start of pass 1
  266. 3090 MOVE #HEX("09A0") TO BLTCON0 :REMark D := A & C (constant)
  267. 3100 MOVE #0 TO BLTCON1 :REMark Ascending pass
  268. 3110 MOVE #-1 TO BLTMASK :REMark Use all bits in first word
  269. 3120 MOVE #-1 TO BLTMASK+2 :REMark Last word, use all bits
  270. 3130 MOVE #0 TO BLTAMOD :REMark Source modulo
  271. 3140 MOVE #2 TO BLTDMOD :REMark Destination modulo
  272. 3150 MOVE #HEX("FF00") TO BLTCDAT :REMark Byte mask
  273. 3160 MOVE #a TO BLTAPT+2 :REMark Source
  274. 3170 MOVE #b TO BLTDPT+2 :REMark Destination
  275. 3180 MOVE #1024 TO DMACON_W :REMark Not Nasty (yet)
  276. 3190 MOVE #c*64+1 TO BLTSIZE
  277. 3200 WAIT 0,0
  278. 3210 IF ShowTime THEN MOVE #HEX("608") TO COLOUR0
  279. 3220 MOVE #2 TO BLTCON1 :REMark DESCENDING pass
  280. 3230 MOVE #a+2046 TO BLTAPT+2 :REMark Source
  281. 3240 MOVE #b+4094 TO BLTDPT+2 :REMark Destination
  282. 3250 MOVE #HEX("89A0") TO BLTCON0 :REMark D := (A * 256) & C
  283. 3260 MOVE #c*64+1 TO BLTSIZE
  284. 3270 WAIT 0,0 :REMark Wait for Blit to finish
  285. 3280 MOVE #page TO BLTDPT :REMark Stay in our page
  286. 3290 MOVE #page TO BLTAPT :REMark Stay in our page
  287. 3300 END DEFine EXPAND_FOUNT
  288. 3310 :
  289. 3320 DEFine PROCedure SETUP_CHAR_BLITS
  290. 3330 IF ShowTime THEN MOVE #5 TO COLOUR0 :REMark Blue during blitting
  291. 3340 IF CharColumns%>40 :MOVE #32768+1024 TO DMACON_W :REMark Get Nasty
  292. 3350 REMark Get set for Character blits
  293. 3360 MOVE #HEX("0DFC") TO BLTCON0 :REMark D := A v B for characters
  294. 3370 MOVE #HEX("8000") TO BLTCON1 :REMark B shift for characters
  295. 3380 MOVE #0 TO BLTBMOD
  296. 3390 MOVE #0 TO BLTAMOD
  297. 3400 MOVE #width%-2 TO BLTDMOD
  298. 3410 END DEFine SETUP_CHAR_BLITS
  299. 3420 :
  300. 3430 DEFine PROCedure MAKE_COPPER_BLITS
  301. 3440 REMark Generate copper list to unpack CharMap and Fount, and blit characters
  302. 3450 REMark Work out start line LIN, staying ahead of the beam
  303. 3460 LIN=top_line%+HeadLines%-CharHeight%-(CharHeight%=8)*((CharLines%+3) DIV 4)
  304. 3470 REMark Allow one extra scan per 32 for short characters, to stay ahead of beam
  305. 3480 IF BlitChars :LIN=LIN-((CharColumns%*CharLines%) DIV 80):REMark Bytes -> CLIST
  306. 3490 IF BlitFount :LIN=LIN-28 :REMark Allow time to unpack 2K fount to 4K
  307. 3500 IF CharColumns%>64 THEN LIN=LIN-CharLines%*2 :REMark Time to unpack CharMap
  308. 3510 WAIT 0,LIN : PRINT #0;"for line ";
  309. 3520 IF LIN<1 THEN PRINT #0;"No time - add HeadLines% if possible." : STOP
  310. 3530 t=CharHeight% :REMark Compute WAIT period between character blits
  311. 3540 SELect ON t:=9 TO 11:GAP=70:=12 TO 16:GAP=t*2+60:=1 TO 8:GAP=58
  312. 3550 IF CharColumns%>64 THEN GAP=GAP-4*(t>8)-2*(t>11):REMark Cut gap, more columns
  313. 3560 COL=GAP:TextLineBytes%=CharColumns%*CharHeight%:Start%=HeadLines%*width%+8192
  314. 3570 IF BlitChars THEN CHARS_TO_CLIST CharMap,CharColumns%*CharLines%
  315. 3580 IF CharColumns%<=40 : GAP=GAP*3/4 :REMark Not Nasty
  316. 3590 IF BlitFount THEN EXPAND_FOUNT fount+4096,fount,1024 :LIN=LIN+28
  317. 3600 SETUP_CHAR_BLITS :REMark Set Blitter registers the same for every character
  318. 3610 IF BlitChars:POKE_W FirstCharMove,copper-pagebase+6 :REMark First channel A ptr
  319. 3620 FOR textline=Start% TO Start%+TextLineBytes%*(CharLines%-1) STEP TextLineBytes%
  320. 3630   N=textline : AT #0,3,32 : PRINT #0,1+(N-Start%) DIV TextLineBytes%;
  321. 3640   FOR i=1 TO CharColumns% DIV 2 : BLIT_CHAR
  322. 3650 END FOR textline
  323. 3660 IF BlitChars:POKE_W LastCharMove,copper-pagebase-18 :REMark Last B word ptr
  324. 3670 IF ShowTime THEN MOVE #0 TO COLOUR0
  325. 3680 END DEFine MAKE_COPPER_BLITS
  326. 3690 :
  327. 3700 DEFine PROCedure CHARS_TO_CLIST(a,c)
  328. 3710 REMark Expand character code bytes at A to Copper list for C characters
  329. 3720 IF ShowTime THEN MOVE #112 TO COLOUR0 :REMark Signal start of pass 1
  330. 3730 IF CharHeight%=8
  331. 3740   MOVE #HEX("0FF0") TO BLTCDAT :REMark Byte mask for *16
  332. 3750   MOVE #HEX("49A0") TO BLTCON0 :REMark D := (A >> 4) & C (constant)
  333. 3760 ELSE 
  334. 3770   MOVE #HEX("1FE0") TO BLTCDAT :REMark CharCode *32
  335. 3780   MOVE #HEX("39A0") TO BLTCON0 :REMark D := (A >> 3) & C (constant)
  336. 3790 END IF 
  337. 3800 MOVE #0 TO BLTCON1 :REMark Ascending pass
  338. 3810 MOVE #-1 TO BLTMASK :REMark Use all bits in first word
  339. 3820 MOVE #-1 TO BLTMASK+2 :REMark Last word, use all bits
  340. 3830 MOVE #0 TO BLTAMOD :REMark Source modulo
  341. 3840 MOVE #18 TO BLTDMOD :REMark Destination modulo
  342. 3850 MOVE #a TO BLTAPT+2 :REMark Source
  343. 3860 MOVE #0 TO BLTDPT+2 :REMark Destination
  344. 3870 FirstCharMove=copper-2 :REMark Where to POKE later
  345. 3880 MOVE #1024 TO DMACON_W :REMark Not Nasty (yet)
  346. 3890 MOVE #c*32+1 TO BLTSIZE
  347. 3900 WAIT 0,0
  348. 3910 IF ShowTime THEN MOVE #60 TO COLOUR0
  349. 3920 MOVE #2 TO BLTCON1 :REMark DESCENDING pass
  350. 3930 IF CharHeight%<>8 THEN MOVE #HEX("59A0") TO BLTCON0
  351. 3940 MOVE #a+c-2 TO BLTAPT+2 :REMark Source
  352. 3950 MOVE #0 TO BLTDPT+2 :REMark Destinationn
  353. 3960 LastCharMove=copper-2 :REMark Last Copper B pointer
  354. 3970 MOVE #c*32+1 TO BLTSIZE
  355. 3980 WAIT 0,0 :REMark Wait for Blit to finish
  356. 3990 END DEFine CHARS_TO_CLIST
  357. 4000 :
  358. 4010 REMark New for version 0.17 - Set up patterns for animated fount
  359. 4015 DEFine PROCedure CHAR_GRID
  360. 4020 patterns=ALCHP(8*8)
  361. 4030 FOR char=0 TO 7
  362. 4035   vline=2^char : REMark Verticals
  363. 4037   base=patterns+char*8
  364. 4040   FOR row=0 TO 7
  365. 4050     POKE base+row,vline
  366. 4060     IF row=char : POKE base+row,255
  367. 4070   END FOR row
  368. 4080 END FOR char
  369. 4090 END DEFine CHAR_GRID
  370.